﻿using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using StarsAdmin.Application.Auth.Dtos;
using StarsAdmin.Application.LoginLog.Dtos;
using StarsAdmin.Application.LoginLog.Services;
using StarsAdmin.Core.App;
using StarsAdmin.Core.Extensions;
using StarsAdmin.Core.Models;
using System.Diagnostics;

namespace StarsAdmin.Web.Core.Filter
{
    /// <summary>
    /// 登录过滤器
    /// </summary>
    public class LoginLogFilter : Attribute, IAsyncActionFilter
    {
        public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
        {
            // 创建一个计时器
            Stopwatch stopwatch = new Stopwatch();
            stopwatch.Start();
            var actionExecutedContext = await next();
            stopwatch.Stop();
            // 获取 HttpContext 和 HttpRequest 对象
            var httpContext = context.HttpContext;
            var httpRequest = httpContext.Request;

            AddLoginLogInput logInput = new AddLoginLogInput();
            logInput.Ip = httpRequest.GetIP();

            logInput.ElapsedMilliseconds = stopwatch.ElapsedMilliseconds;
            // 客户端浏览器信息
            var userAgent = httpRequest.Headers["User-Agent"];
            if (!string.IsNullOrWhiteSpace(userAgent))
            {
                var client = UAParser.Parser.GetDefault().Parse(userAgent);
                logInput.UserAgent = userAgent.ToString();
                logInput.Device = client.Device.Family;
                logInput.Browser = client.Browser.Family;
                logInput.Os = client.OS.Family;
            }
            // 获取方法参数
            if (context.ActionArguments.TryGetValue("input", out var value))
            {
                logInput.UserName = ((LoginInput)value).UserName;
            }
            // 读取返回结果
            var result = actionExecutedContext.Result;
            if (result is ObjectResult objectResult)
            {
                var resultValue = objectResult.Value as ResultModel<CurrentUserDto>;
                if (resultValue != null)
                {
                    logInput.IsSuccess = resultValue.IsSuccess;
                    logInput.Message = resultValue.Message;
                    logInput.StatusCode = resultValue.Code;
                }
            }
            // 获取异常对象情况
            var exception = actionExecutedContext.Exception;
            // 判断是否是验证异常
            if (exception != null)
            {
                logInput.IsSuccess = false;
                logInput.Message = exception.Message;
            }
            // 获取服务
            var logService = AppHelper.GetService<ILoginLogService>();
            if (logService != null)
            {
                await logService.AddAsync(logInput);
            }
        }
    }
}